﻿using System;
using System.Collections.Generic;
using System.Linq;
using Mnk.Merger.Code.Commands;

namespace Mnk.Merger.Code.UI
{
    class SpyUi : ISpyUi
    {
        private readonly IMergeSpy mergeSpy;

        public SpyUi(IMergeSpy mergeSpy)
        {
            this.mergeSpy = mergeSpy;
        }

        public void Collect(string sourceUrl, string targetUrl, string revisionFrom)
        {
            var changes = mergeSpy.GetChanges(sourceUrl, targetUrl, revisionFrom).ToList();
            if (changes.Count < 2 )
            {
                Console.WriteLine("No changes");
                return;
            }
            var totalProjects = 0;
            var totalCommits = changes.First().Commits;
            var revisions = changes.First().Revisions;
            changes.RemoveAt(0);
            var totalChangedFiles = 0;
            var max = changes.Max(x => x.ProjectName.Length);
            Console.WriteLine("{0}| {1}| {2}| {3}|",
                Prepare("Project Name", max),
                Prepare("Commits", 8),
                Prepare("Changed", 8),
                Prepare("Breaking commits/files", 22)
                );
            var breaking = new List<MergeSpyInfo>();
            foreach (var project in changes)
            {
                Console.WriteLine("{0}| {1}| {2}| {3}| {4}|", 
                    Prepare(project.ProjectName, max), 
                    Prepare(project.Commits.ToString(), 8), 
                    Prepare(project.ChangedFiles.ToString(), 8),
                    Prepare(project.BreakingChanges.Select(x => x.Id).Distinct().Count().ToString(), 10),
                    Prepare(project.BreakingChanges.Distinct().Count().ToString(), 10)
                    );
                breaking.AddRange(project.BreakingChanges);
                totalProjects++;
                totalChangedFiles += project.ChangedFiles;
            }
            Console.WriteLine();
            Console.WriteLine("Total:");
            Console.WriteLine("Projects: {0}, commits: {1}, changed files:{2}, breaking commits: {3}, breaking files: {4}",
                totalProjects, totalCommits, totalChangedFiles, breaking.Select(x => x.Id).Distinct().Count(), breaking.Distinct().Count());
            Console.WriteLine();
            Console.WriteLine("Changes in the same files(breaking):");
            foreach (var path in breaking.Select(x=>x.Path).OrderBy(x=>x).GroupBy(x=>x))
            {
                Console.WriteLine(path.Key + "\t (" + path.Count() + ")");
            }
            Console.WriteLine("Revisions to merge:");
            foreach (var revision in revisions)
            {
                Console.WriteLine(revision);
            }
        }

        private static string Prepare(string projectName, int max)
        {
            if (projectName.Length < max)
            {
                return projectName.PadRight(max, ' ');
            }
            return projectName;
        }
    }
}